package com.xxg.fileshand.reader

import android.content.Context
import android.media.SoundPool
import android.os.Handler
import android.os.Looper
import android.os.Message
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ToastUtils
import com.rscja.deviceapi.RFIDWithUHFUART
import com.rscja.deviceapi.entity.UHFTAGInfo
import com.xxg.fileshand.R
import com.xxg.fileshand.app.App
import com.xxg.fileshand.app.SetInfo
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.lang.ref.WeakReference


class ReaderUtils {

    //懒汉式单例
    companion object {
        val instance: ReaderUtils by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            ReaderUtils()
        }
    }

    private var mReader: RFIDWithUHFUART? = null
    private lateinit var mSoundPool: SoundPool

    private val epcList by lazy { ArrayList<String>() }
    private val tidList by lazy { ArrayList<String>() }
    private var job: Job? = null
    private val mHandler by lazy { MyHandler(this) }

    /**
     * 是否初始化成功
     */
    private var _isInit: Boolean? = null
    val isInit
        get() = _isInit

    /**
     * 是否在读卡
     */
    private val isScanning by lazy { MutableLiveData(false) }
    val isScanningRFID: LiveData<Boolean> = isScanning

    /**
     * 循环读的标志
     */
    private var loopFlag = false

    /**
     * 读到标签是否播放音效
     */
    var playSoundFlag = true

    /**
     * 是否显示开始和停止的提示
     */
    var showStartAndStopMsg = true

    var delay = 10L

    var callBack: WeakReference<CallBack>? = null

    var needReadTid: String? = null

    fun initReader(context: Context) {
        mSoundPool = SoundPool.Builder().setMaxStreams(2).build()
        mSoundPool.load(App.getContext(), R.raw.barcodebeep, 1)
        mSoundPool.load(App.getContext(), R.raw.serror, 2)

        try {
            mReader = RFIDWithUHFUART.getInstance()
            CoroutineScope(Dispatchers.Default).launch {
                if (mReader?.init(context) == true) {
                    _isInit = true
                    mReader?.setEPCAndTIDMode()
                    setPower(SetInfo.getScanWzPower())
                    ToastUtils.showShort("设备初始化成功")
                } else {
                    _isInit = false
                    ToastUtils.showShort("设备初始化失败")
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            _isInit = false
            ToastUtils.showShort("设备初始化失败")
        }
    }

    /**
     * 扫描按钮
     */
    fun isScanBtn(keyCode: Int) =
        keyCode == 139 || keyCode == 280 || keyCode == 293 || keyCode == 131

    @Synchronized
    fun startScan() {
        if (isInit != true) {
            LogUtils.d("=====not init")
            return
        }
        LogUtils.d("=====clickStart")
        if (!isScanning()) {
            //开始读卡成功
            if (mReader?.startInventoryTag() == true) {
                LogUtils.e("startInventoryTag")
                isScanning.value = true
                loopFlag = true
                if (showStartAndStopMsg) {
//                    ToastUtils.showShort("开始扫描")
                }
                job = CoroutineScope(Dispatchers.Default).launch {
                    var tag: UHFTAGInfo?
                    while (isActive && loopFlag) {
                        delay(delay)
                        tag = mReader?.readTagFromBuffer()
                        if (tag != null) {
                            if ((needReadTid == null && !tidList.contains(tag.tid)) || (needReadTid != null && needReadTid == tag.tid)) {
                                val msg = mHandler.obtainMessage()
                                msg.obj = tag
                                mHandler.sendMessage(msg)
                                if (!tidList.contains(tag.tid)) {
                                    tidList.add(tag.tid)
                                }
                            }
                        } else {
//                            LogUtils.d("=====tag is null")
                        }
                    }
                }
            }
//            else {
//                reset()
//            }
        } else {
//            stopScan()
        }
    }

    /**
     * 停止扫描
     */
    @Synchronized
    fun stopScan() {
        if (isScanning()) {
            loopFlag = false
            job?.cancel()
            isScanning.value = mReader?.stopInventory() != true
            if (!isScanning() && showStartAndStopMsg) {
//                ToastUtils.showShort("停止成功")
            }
            //停止失败
            if (isScanning()) {
                ToastUtils.showShort("停止失败")
            }
        }
        mHandler.removeCallbacksAndMessages(null)
    }

    @Synchronized
    fun readData(epcOrTid: String, isEpc: Boolean = true): String? {
        /**
         * 访问密码/过滤类型/过滤数据的起始地址/过滤数据长度/过滤数据内容/存储区/地址/长度
         */
        return mReader?.readData("00000000", RFIDWithUHFUART.Bank_TID, 0, 96, epcOrTid, 0, 4, 2)
    }

    fun reset() {
        stopScan()
        resetData()
    }

    fun resetData() {
        tidList.clear()
    }

    fun removeEpc(epc: String?) {
        epc?.let {
            epcList.remove(it)
        }
    }

    fun removeTid(tid: String?) {
        tid?.let {
            tidList.remove(it)
        }
    }

    /**
     * 释放资源
     */
    fun release() {
        mReader?.free()
        mSoundPool.release()
    }

    /**
     * 设置功率
     */
    fun setPower(power: Int) {
        CoroutineScope(Dispatchers.Default).launch {
            try {
                if (mReader?.setPower(power) != true) {
                    ToastUtils.showShort("设置功率失败")
                } else {
                    callBack?.get()?.setPowerSuccess(power)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }

        }
    }

    /**
     * 获取功率
     */
    fun getPower() {
        if (isInit != true) {
            return
        }
        CoroutineScope(Dispatchers.Default).launch {
            try {
                val power = mReader?.power ?: 0
                callBack?.get()?.returnPower(power)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    private fun isScanning(showToast: Boolean = false): Boolean {
        val result = isScanningRFID.value ?: false
        if (showToast && result) {
            ToastUtils.showShort("正在扫描中")
        }
        return result
    }

    fun playAudio() {
        mSoundPool.play(1, 1.0f, 1.0f, 0, 0, 1.0f)
    }

    fun playAudioError() {
        mSoundPool.play(2, 1.0f, 1.0f, 0, 0, 1.0f)
    }

    class MyHandler(read: ReaderUtils) : Handler(Looper.getMainLooper()) {

        private val mRef = WeakReference(read)

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            mRef.get()?.run {
                //标签去重
                val info = msg.obj as UHFTAGInfo
                if (playSoundFlag) {
                    playAudio()
                    LogUtils.e("***playAudio")
                }
                try {
                    if (callBack == null || callBack?.get() == null) {
                        LogUtils.e("callBack is null")
                    }
                    callBack?.get()?.readEpc(info)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    }

    /**
     * 消息回调
     */
    interface CallBack {

        fun readEpc(tagInfo: UHFTAGInfo)

        fun returnPower(power: Int)

        fun setPowerSuccess(power: Int)

    }

}